﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System.IdentityModel.Tokens.Jwt;
using QW.Found.JwtAuthorize;
using static QW.Found.JwtAuthorize.TokenBuilder;
using QW.Found;
using System.Security.Claims;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;

namespace QW.Found.JwtAuthorize
{
    /// <summary>
    /// 登录用户提供者
    /// </summary>
    public class PrincipalUserProvider
    {
        /// <summary>
        /// 实例
        /// </summary>
        // public static AuthorizeProvider Instance { get; private set; }
        /// <summary>
        /// 令牌构建器
        /// </summary>
        private readonly ITokenBuilder _tokenBuilder;
        /// <summary>
        /// 上下文访问器
        /// </summary>
        private readonly IHttpContextAccessor _httpContextAccessor;
        /// <summary>
        /// 授权验证提供者
        /// </summary>
        /// <param name="tokenBuilder"></param>
        /// <param name="httpContextAccessor"></param>
        public PrincipalUserProvider(ITokenBuilder tokenBuilder, IHttpContextAccessor httpContextAccessor)
        {
            _tokenBuilder = tokenBuilder;
            this._httpContextAccessor = httpContextAccessor;
            // Instance = this;
        }

        /// <summary>
        /// 获取当前登录用户信息
        /// </summary>
        /// <returns></returns>
        public PrincipalUser<T> GetCurrentPrincipalUser<T>()
        {
            var user = _httpContextAccessor.HttpContext.User;
            PrincipalUser<T> CurrentUser = null;
            if (user != null && user.Identity.IsAuthenticated)
            {
                CurrentUser = new PrincipalUser<T>();
                CurrentUser.LoginId = user.FindFirst(JwtRegisteredClaimNames.Jti)?.Value;
                CurrentUser.UserId = user.FindFirst(JwtRegisteredClaimNames.Sid)?.Value;
                CurrentUser.Role = user.FindFirst(ClaimTypes.Role)?.Value;
                CurrentUser.ShowName = user.FindFirst("ShowName")?.Value;
                CurrentUser.RemoteIp = user.FindFirst("RemoteIp")?.Value;
                CurrentUser.LoginTime = DateTime.Parse(user.FindFirst("LoginTime")?.Value);
                var _ext = user.FindFirst("External")?.Value;
                if (!string.IsNullOrWhiteSpace(_ext))
                {
                    CurrentUser.External = JsonConvert.DeserializeObject<T>(_ext);
                }
            }
            return CurrentUser;
        }
        /// <summary>
        /// 构建令牌
        /// </summary>
        /// <param name="user"></param>
        /// <param name="expires">过期时间</param>
        /// <param name="notBefore">此时间后才会生效</param>
        /// <returns></returns>
        public TokenInfo BuildToken<T>(PrincipalUser<T> user, DateTime expires, DateTime? notBefore = null)
        {
            if (user == null)
            {
                throw new BusinessException("错误的用户信息");
            }
            var claimList = new List<Claim>
            {
                new Claim(JwtRegisteredClaimNames.Jti,user.LoginId.ToString()),   //登录编号与令牌编号
                new Claim(JwtRegisteredClaimNames.Sid,user.UserId.ToString()),  //登录用户编号
                new Claim(ClaimTypes.Role,user.Role), // 角色
                new Claim("ShowName", user.ShowName),
                new Claim("RemoteIp",  user.RemoteIp),
                new Claim("LoginTime",user.LoginTime.ToString("yyyy-MM-dd HH:mm:ss")),
                new Claim("External",JsonConvert.SerializeObject(user.External))
                    };
            var token = _tokenBuilder.BuildJwtToken(claimList, expires, notBefore);
            return token;

        }
    }
}
